package socket.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * @description: 类描述
 * @author: Fesine
 * @createTime:2016/9/29 18:45
 * @update:修改内容
 * @author: Fesine
 * @updateTime:2016/9/29 18:45
 */
public class NIOServer {
    private ByteBuffer readBuffer;
    private Selector selector;

    public static void main(String[] args) {
        NIOServer server = new NIOServer();
        server.init();
        server.listen();
    }
    private void init() {
        readBuffer = ByteBuffer.allocate(1024);
        ServerSocketChannel socketChannel;
        try {
            socketChannel = ServerSocketChannel.open();
            socketChannel.configureBlocking(false);
            //绑定端口
            socketChannel.socket().bind(new InetSocketAddress(8383));
            selector = Selector.open();
            socketChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void listen() {
        while (true) {
            try {
                selector.select();
                Iterator iter = selector.selectedKeys().iterator();
                while (iter.hasNext()) {
                    SelectionKey key = (SelectionKey) iter.next();
                    iter.remove();//确保不重复处理
                    handleKey(key);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void handleKey(SelectionKey key) throws IOException {
        SocketChannel channel = null;
        try {
            if (key.isAcceptable()) {
                ServerSocketChannel socketChannel = (ServerSocketChannel) key.channel();
                channel = socketChannel.accept();
                channel.configureBlocking(false);
                channel.register(selector, SelectionKey.OP_READ);
            } else if (key.isReadable()) {
                channel = (SocketChannel) key.channel();
                readBuffer.clear();
                CharBuffer charBuffer = CharsetHelper.decode(readBuffer);
                String question = charBuffer.toString();
                String answer = getAnswer(question);
                channel.write(CharsetHelper.encode(CharBuffer.wrap(answer)));
            } else {
                channel.close();
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            if (channel != null) {
                channel.close();
            }
        }
    }

    private String getAnswer(String question) {
        String answer = null;
        switch (question) {
            case "who":
                answer = "my name is fesine";
                break;
            case "what":
                answer = "do IT!";
                break;
            case "where":
                answer = "from jiangsu wuxi";
                break;
            default:
                answer = "请输入who,what,where";
        }
        return answer;
    }
}
